package io.geekidea.boot.auth.controller;

import com.hwtx.form.controller.Api2Result;
import com.hwtx.form.util.JacksonUtil;
import io.geekidea.boot.auth.cache.LoginCache;
import io.geekidea.boot.auth.dto.LoginDto;
import io.geekidea.boot.auth.service.LoginRedisService;
import io.geekidea.boot.auth.service.LoginService;
import io.geekidea.boot.auth.util.LoginUtil;
import io.geekidea.boot.auth.vo.LoginTokenVo;
import io.geekidea.boot.auth.vo.LoginVo;
import io.geekidea.boot.common.constant.LoginConstant;
import io.geekidea.boot.common.constant.SystemConstant;
import io.geekidea.boot.config.properties.LoginAdminProperties;
import io.geekidea.boot.util.CookieUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * @author geekidea
 **/
@Slf4j
@RestController
@Tag(name = "管理后台登录")
@RequestMapping("/admin")
public class LoginController {

    @Resource
    private LoginService loginService;
    @Resource
    private LoginRedisService loginRedisService;
    @Resource
    private LoginAdminProperties loginAdminProperties;

    /**
     * 管理后台登录
     */
    @PostMapping("/login")
    @Operation(summary = "管理后台登录")
    public Api2Result login(@Valid @RequestBody LoginDto loginDto, @CookieValue(value = "locale", defaultValue = SystemConstant.DEFAULT_LOCALE) String locale, HttpServletRequest request, HttpServletResponse response) {
        try {
            LoginTokenVo loginTokenVo = loginService.login(loginDto, locale);
            // 输出token到cookie
            CookieUtil.addCookie(LoginConstant.ADMIN_COOKIE_TOKEN_NAME, loginTokenVo.getToken(), request, response);
            return Api2Result.success(loginTokenVo);
        } catch (Exception e) {
            log.error("管理后台登录异常", e);
            return Api2Result.fail("登陆失败");
        }
    }

    @PostMapping("/pure/login")
    @Operation(summary = "管理后台登录")
    public Api2Result preLogin(@Valid @RequestBody LoginDto loginDto, @CookieValue(value = "locale", defaultValue = SystemConstant.DEFAULT_LOCALE) String locale) {
        try {
            LoginTokenVo loginTokenVo = loginService.login(loginDto, locale);
            loginTokenVo.getLoginVo().setAccessToken(loginTokenVo.getToken());
            loginTokenVo.getLoginVo().setRefreshToken(loginTokenVo.getToken());
            LoginVo loginVo = loginTokenVo.getLoginVo();
            loginVo.setExpires(getDateAfterSevenDays());
            return Api2Result.success(loginVo);
        } catch (Exception e) {
            log.error("管理后台登录异常", e);
            return Api2Result.fail(e.getMessage());
        }
    }

    @PostMapping("/refresh-token")
    @Operation(summary = "管理后台登录")
    public Api2Result refreshToken(@RequestBody String token) {
        LoginVo loginVo = LoginCache.get();
        try {
            String refreshToken = null;
            if (loginVo == null) {
                if (StringUtils.isEmpty(token)) {
                    return Api2Result.fail("登录无效");
                }
                Map<String, Object> map = JacksonUtil.json2Map(token);
                if (map.get("refreshToken") != null) {
                    refreshToken = map.get("refreshToken").toString();
                }
            }
            if (refreshToken == null) {
                return Api2Result.fail("登录无效，refreshToken不存在");
            }
            loginVo = LoginUtil.getLoginVo(refreshToken);
            if (loginVo == null) {
                return Api2Result.fail("登录无效，refreshToken已失效");
            }
            loginVo.setRefreshToken(refreshToken);
            loginVo.setAccessToken(refreshToken);
            loginVo.setExpires(getDateAfterSevenDays());
            loginRedisService.setLoginVo(refreshToken, loginVo);
        } catch (Exception e) {
            log.error("管理后台登录异常", e);
            return Api2Result.fail("登陆失败");
        }
        return Api2Result.success(loginVo);
    }

    private Date getDateAfterSevenDays() {
        Calendar calendar = Calendar.getInstance();
        Integer expireMins = loginAdminProperties.getTokenExpireMinutes();
        calendar.add(Calendar.DAY_OF_YEAR, expireMins / 1440);
        return calendar.getTime();
    }

    /**
     * 获取管理后台登录用户信息
     */
    @RequestMapping("/getLoginUserInfo")
    @Operation(summary = "获取管理后台登录用户信息")
    public Api2Result getLoginUserInfo() {
        LoginVo loginVo = loginService.getLoginUserInfo();
        return Api2Result.success(loginVo);
    }

    /**
     * 管理后台退出
     */
    @PostMapping("/logout")
    @Operation(summary = "管理后台退出")
    public Api2Result logout(HttpServletRequest request, HttpServletResponse response) {
        // 删除缓存
        loginService.logout();
        // 从cookie中删除token
        CookieUtil.deleteCookie(LoginConstant.ADMIN_COOKIE_TOKEN_NAME, request, response);
        return Api2Result.success();
    }

}
